package com.kingmed.kmss.admin.modules.ums.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kingmed.kmss.admin.modules.ums.mapper.UmsBpmnGroupMapper;
import com.kingmed.kmss.admin.modules.ums.model.UmsBpmnGroup;
import com.kingmed.kmss.admin.modules.ums.service.UmsBpmnGroupService;
import com.kingmed.kmss.admin.modules.ums.service.UmsBpmnMembershipService;
import com.kingmed.kmss.common.bo.bpmn.GroupBO;
import com.kingmed.kmss.common.dto.admin.ums.BpmnGroupDTO;
import com.kingmed.kmss.common.dto.admin.ums.BpmnQueryDTO;
import com.kingmed.kmss.common.exception.BusinessException;
import com.kingmed.kmss.common.utils.BeanCopyUtils;
import com.kingmed.kmss.common.utils.MessageUtils;
import com.kingmed.kmss.framework.feign.client.bpmn.RemoteBpmnGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 后台流程角色表 服务实现类
 * </p>
 *
 * @author wyl
 * @since 2023-02-17
 */
@Service
public class UmsBpmnGroupServiceImpl extends ServiceImpl<UmsBpmnGroupMapper, UmsBpmnGroup> implements UmsBpmnGroupService {

    @Autowired
    private UmsBpmnMembershipService membershipService;

    @Autowired
    private RemoteBpmnGroupService remoteBpmnGroupService;

    @Transactional
    @Override
    public int update(List<BpmnGroupDTO> reqDto) {
        for (BpmnGroupDTO dto : reqDto) {
            if (codeExist(dto) || nameExist(dto)) {
                throw new BusinessException(MessageUtils.message("bpmn_group_code_name_exist"));
            }
        }
        List<UmsBpmnGroup> entityList = BeanCopyUtils.copyList(reqDto, UmsBpmnGroup.class);
        if (entityList == null) {
            return 0;
        }
        for (UmsBpmnGroup group : entityList) {
            this.saveOrUpdate(group);

            this.bpmnCreateGroup(group);
        }
        return reqDto.size();
    }

    private boolean codeExist(BpmnGroupDTO dto) {
        List<UmsBpmnGroup> groupList = this.list(new LambdaQueryWrapper<UmsBpmnGroup>()
                .eq(UmsBpmnGroup::getGroupKey, dto.getGroupKey())
                .ne(dto.getId() != null, UmsBpmnGroup::getId, dto.getId()));
        return CollectionUtils.isNotEmpty(groupList);
    }

    private boolean nameExist(BpmnGroupDTO dto) {
        List<UmsBpmnGroup> groupList = this.list(new LambdaQueryWrapper<UmsBpmnGroup>()
                .eq(UmsBpmnGroup::getGroupName, dto.getGroupName())
                .ne(dto.getId() != null, UmsBpmnGroup::getId, dto.getId()));
        return CollectionUtils.isNotEmpty(groupList);
    }

    private void bpmnCreateGroup(UmsBpmnGroup entity) {
        GroupBO groupBO = new GroupBO();
        groupBO.setGroupId(entity.getGroupKey());
        groupBO.setType(entity.getGroupKey());
        groupBO.setName(entity.getGroupName());
        remoteBpmnGroupService.createGroup(groupBO);
    }

    @Transactional
    @Override
    public int delete(List<Long> idList) {
        List<UmsBpmnGroup> entityList = this.listByIds(idList);

        this.removeBatchByIds(idList);
        membershipService.deleteByGroupId(idList);

        this.bpmnDeleteGroup(entityList);

        return idList.size();
    }

    private void bpmnDeleteGroup(List<UmsBpmnGroup> entityList) {
        for (UmsBpmnGroup entity : entityList) {
            GroupBO groupBO = new GroupBO();
            groupBO.setGroupId(entity.getGroupKey());
            groupBO.setType(entity.getGroupKey());
            groupBO.setName(entity.getGroupName());
            remoteBpmnGroupService.deleteGroup(groupBO);
        }
    }

    @Override
    public Page<BpmnGroupDTO> pageList(BpmnQueryDTO queryDTO) {
        Page<UmsBpmnGroup> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        QueryWrapper<UmsBpmnGroup> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<UmsBpmnGroup> lambda = wrapper.lambda();
        if (StrUtil.isNotEmpty(queryDTO.getGroupName())) {
            lambda.like(UmsBpmnGroup::getGroupName, queryDTO.getGroupName());
        }
        page = this.page(page, wrapper);
        return this.toDtoPage(page);
    }

    private Page<BpmnGroupDTO> toDtoPage(Page<UmsBpmnGroup> resultPage) {
        Page<BpmnGroupDTO> dtoPage = new Page<>(resultPage.getCurrent(), resultPage.getSize(), resultPage.getTotal(), resultPage.searchCount());
        if (CollectionUtils.isEmpty(resultPage.getRecords())) {
            return dtoPage;
        }
        dtoPage.setRecords(BeanCopyUtils.copyList(resultPage.getRecords(), BpmnGroupDTO.class));
        return dtoPage;
    }

    @Override
    public List<BpmnGroupDTO> queryList(BpmnQueryDTO queryDTO) {
        QueryWrapper<UmsBpmnGroup> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<UmsBpmnGroup> lambda = wrapper.lambda();
        if (StrUtil.isNotEmpty(queryDTO.getGroupName())) {
            lambda.like(UmsBpmnGroup::getGroupName, queryDTO.getGroupName());
        }
        if (StrUtil.isNotEmpty(queryDTO.getGroupKey())) {
            lambda.eq(UmsBpmnGroup::getGroupKey, queryDTO.getGroupKey());
        }
        List<UmsBpmnGroup> groupList = this.list(wrapper);
        return BeanCopyUtils.copyList(groupList, BpmnGroupDTO.class);
    }
}
